/**
 * 文件名:  HttpResponse.java
 * 版权:    Copyright 2000-2011 Huawei Tech. Co. Ltd. All Rights Reserved.
 * 创建人:  tangzhixiong
 * 文件描述:  
 * 修改时间: 2011-6-10 下午03:12:23
 * 修改内容： 新增
 */
package com.huawei.virest.common.domain;

import java.io.InputStreamReader;
import java.io.Reader;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.Header;
import org.apache.http.HeaderElement;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.util.CharArrayBuffer;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import com.google.gson.GsonBuilder;
import com.huawei.virest.common.util.Utils;

/**
 * 类描述：HttpResp
 * @author tangzhixiong
 * @version snsgw V100R001
 */
public class HttpResp
{
    private static final int ONE_G = 1024;
    
    private static final int FOUR_G = 4096;

    private static Log logger = LogFactory.getLog(HttpResp.class);

    private char[] httpResponseBody = null;

    private Header[] httpResponseHeaders = null;

    private String contentType = null;

    private String contentEncoding = null;

    /**
     * httpStatus
     */
    private int httpStatus;

    /**
     * statusText 微博内容
     */
    private String statusText;

    /**
     * response响应
     */
    private String response = null;
    /**
     * 默认构造函数
     */
    public HttpResp()
    {
    }
    
    /**
     * 构造函数
     * @param response response
     */
    public HttpResp(HttpResponse response)
    {
        if (response != null)
        {
            httpStatus = response.getStatusLine().getStatusCode();
            HttpEntity entity = response.getEntity();
            if (entity != null)
            {
                try
                {
                    httpResponseBody = readBytesFromInputStream(entity);
                }
                catch (IllegalStateException e)
                {
                    logger.error(e.toString());
                }
                catch (Exception e)
                {
                    logger.error(e.toString());
                }
                httpResponseHeaders = response.getAllHeaders();
            }

            if (null != response.getEntity())
            {
                Header contentTypeHeader = response.getEntity().getContentType();
                if (contentTypeHeader != null)
                {
                    contentType = contentTypeHeader.getValue();
                }
                Header contentEncodingHeader = response.getEntity().getContentEncoding();
                if (contentEncodingHeader != null)
                {
                    contentEncoding = contentEncodingHeader.getValue();
                }
            }
        }
        else
        {
            logger.info("response is null");
        }
    }

    public int getHttpStatus()
    {
        return httpStatus;
    }
    
    public void setHttpStatus(int httpStatus)
    {
        this.httpStatus = httpStatus;
    }
    
    /**
     * 获得响应
     * @return [参数说明]
     * @see [类、类#方法、类#成员]
     */
    public String getResponse()
    {
        if (!Utils.isNull(response))
        {
            return response;
        }
        return getHttpResponseBodyAsString();
    }
    
    public void setResponse(String response)
    {
        this.response = response;
    }
    
    public String getStatusText()
    {
        return statusText;
    }
    
    public void setStatusText(String statusText)
    {
        this.statusText = statusText;
    }
    
    /**
     * 获得内容字符集
     * @param entity entity
     * @return String [返回类型说明]
     * @see [类、类#方法、类#成员]
     */
    public static String getContentCharSet(final HttpEntity entity)
    {
        if (entity == null)
        {
            throw new IllegalArgumentException("HTTP entity may not be null");
        }
        String charset = null;
        if (entity.getContentType() != null)
        {
            HeaderElement values[] = entity.getContentType().getElements();
            if (values.length > 0)
            {
                NameValuePair param = values[0].getParameterByName("charset");
                if (param != null)
                {
                    charset = param.getValue();
                }
            }
        }
        return charset;
    }
    
    /**
     * Read up bytes from given InputStream instance and return
     * 
     * @param entity (given InputStream instance is not closed by this function)
     * @return char[]
     */
    public static char[] readBytesFromInputStream(HttpEntity entity)
    {
        try
        {
            int i = (int) entity.getContentLength();
            if (i < 0)
            {
                i = FOUR_G;
            }
            String charset = getContentCharSet(entity);
            Reader reader = new InputStreamReader(entity.getContent(), charset);
            CharArrayBuffer buffer = new CharArrayBuffer(i);
            char[] tmp = new char[ONE_G];
            int l;
            while ((l = reader.read(tmp)) != -1)
            {
                buffer.append(tmp, 0, l);
            }
            return buffer.toCharArray();
        }
        catch (Exception e)
        {
            logger.error("readBytesFromInputStream() read bytes from inputStream failed", e);
        }

        return new char[]{};
    }

    /**
     * return mime type of given file
     * 
     * @param file
     * @return when mime type is unknown, it simply returns
     * "application/octet-stream"
     *//*
    public static String getMimeType(File file)
    {
        String mimeType = null;
        try
        {
            mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(
                    MimeTypeMap.getFileExtensionFromUrl(file.getCanonicalPath()));
        }
        catch (IOException e)
        {
            log.error(e.toString());
        }
        if (mimeType == null)
            mimeType = "application/octet-stream";

        return mimeType;
    }*/

    /**
     * jsonToObject
     * @param <T> t
     * @param clazz 类名
     * @return [参数说明]
     * @see [类、类#方法、类#成员]
     */
    public <T> T jsonToObject(Class<T> clazz)
    {
        return new GsonBuilder().create().fromJson(response, clazz);
    }
    
    /**
     * 将相应结果返回为JSONArray
     * @return JSONObject
     * @throws JSONException JSONException
     */
    public JSONObject asJSONObject() throws JSONException
    {
        return new JSONObject(response);
    }
    
    /**
     * 将相应结果返回为JSONArray
     * @return JSONArray
     * @throws JSONException JSONException
     */
    public JSONArray asJSONArray() throws JSONException
    {
    	return new JSONArray(response);
    }
    
    /**
     * <一句话功能简述>
     * <功能详细描述>
     * @return char[] [返回类型说明]
     * @see [类、类#方法、类#成员]
     */
    public char[] getHttpResponseBody()
    {
        if (httpResponseBody == null)
        {
            return new char[0];
        }
        return httpResponseBody;
    }
    
    /**
     * <一句话功能简述>
     * <功能详细描述>
     * @return String [返回类型说明]
     * @see [类、类#方法、类#成员]
     */
    public String getHttpResponseBodyAsString()
    {
        if (httpResponseBody == null)
        {
            return "";
        }
        return new String(httpResponseBody);
    }
    
    /**
     * 获得httpResponseHeaders
     * @return empty array if not known
     */
    public Header[] getHttpResponseHeaders()
    {
        if (httpResponseHeaders == null)
        {
            return new Header[0];
        }
        return httpResponseHeaders;
    }
    
    /**
     * 获得contentType
     * @return empty string if not known
     */
    public String getContentType()
    {
        if (contentType == null)
        {
            return "";
        }
        return contentType;
    }
    
    /**
     * 获得contentEncoding
     * @return null if not known
     */
    public String getContentEncoding()
    {
        return contentEncoding;
    }
}
